package com.oba.base.dao.pager;

import javax.el.ValueExpression;
import javax.faces.component.UIComponent;
import javax.faces.component.html.HtmlPanelGroup;
import javax.faces.context.FacesContext;
import javax.faces.event.AbortProcessingException;
import javax.faces.event.ActionEvent;
import javax.faces.event.FacesEvent;
import javax.faces.event.PhaseId;

import com.icesoft.faces.component.CSS_DEFAULT;
import com.icesoft.faces.component.datapaginator.PaginatorActionEvent;
import com.icesoft.faces.component.ext.taglib.Util;
import com.oba.base.dao.DBDataModel;
import com.oba.base.interfaces.IPager;

public class UIPager extends HtmlPanelGroup {

	public static int DEFAULT_PAGE_SIZE = 10;
	private static final String FIRST_FACET_NAME = "first";
	private static final String LAST_FACET_NAME = "last";
	private static final String NEXT_FACET_NAME = "next";
	private static final String PREVIOUS_FACET_NAME = "previous";
	private static final String GOTO_FACET_NAME = "goto";
	private static final String INFO_FACET_NAME = "info";
	public static final String FACET_FIRST = "first".intern();
	public static final String FACET_PREVIOUS = "previous".intern();
	public static final String FACET_NEXT = "next".intern();
	public static final String FACET_LAST = "last".intern();
	public static final String FACET_GOTO = "goto".intern();
	private transient IPager pager;
	private Boolean immediate;
	private Object _for;
	private String pagerVar;
	private Object[] values;

	@Override
	public String getFamily() {
		return "com.oba.pager";
	}

	@Override
	public String getRendererType() {
		return "com.oba.pager";
	}

	public String getPagerVar() {
		return pagerVar;
	}

	public void setPagerVar(String pagerVar) {
		this.pagerVar = pagerVar;
	}

	public void setFor(Object _for) {
		this._for = _for;
	}

	public Boolean isImmediate() {
		return (Boolean) getPropValue(immediate, "immediate", Boolean.FALSE);
	}

	public void setImmediate(Boolean immediate) {
		this.immediate = immediate;
	}

	public String getscrollButtonCellClass() {
		return Util.getQualifiedStyleClass(this,
				CSS_DEFAULT.DATA_PAGINATOR_SCROLL_BUTTON_CELL_CLASS);
	}

	public UIComponent getFirst() {
		return (UIComponent) getFacets().get(FIRST_FACET_NAME);
	}

	public UIComponent getPrevious() {
		return (UIComponent) getFacets().get(PREVIOUS_FACET_NAME);
	}

	public UIComponent getNext() {
		return (UIComponent) getFacets().get(NEXT_FACET_NAME);
	}

	public UIComponent getLast() {
		return (UIComponent) getFacets().get(LAST_FACET_NAME);
	}

	public UIComponent getGoto() {
		return (UIComponent) getFacets().get(GOTO_FACET_NAME);
	}

	public UIComponent getInfo() {
		return (UIComponent) getFacets().get(INFO_FACET_NAME);
	}

	public IPager getPager() {
		if (pager == null) {
			String forTable = null;
			if (_for != null) {
				forTable = (String) _for;
			} else {
				ValueExpression ve = getValueExpression("for");
				Object val = ve.getValue(getFacesContext().getELContext());
				if (val instanceof String) {
					forTable = (String) val;
				} else if (val instanceof DBDataModel) {
					pager = ((DBDataModel) val).getPager();
				}
			}
//			if (forTable != null) {
//				try {
//					UIData forComp = (UIData) D2DViewHandler.findComponent(
//							forTable, this);
//					pager = new MemoryPager(forComp,forTable);
//				} catch (Exception e) {
//					e.printStackTrace();
//				}
//			}
		}
		return pager;
	}

	public void queueEvent(FacesEvent event) {
		if (event != null && event instanceof ActionEvent) {
			if (isImmediate()) {
				event.setPhaseId(PhaseId.APPLY_REQUEST_VALUES);
			} else {
				event.setPhaseId(PhaseId.INVOKE_APPLICATION);
			}
		}
		super.queueEvent(event);
	}

	public void broadcast(FacesEvent event) throws AbortProcessingException {
		super.broadcast(event);
		IPager pager = getPager();
		if (event instanceof DelayActionEvent) {
			event.queue();
		}else if (event instanceof PaginatorActionEvent) {
			PaginatorActionEvent scrollerEvent = (PaginatorActionEvent) event;
			int pageindex = scrollerEvent.getPageIndex();
			if (pageindex == -1) {
				String facet = scrollerEvent.getScrollerfacet();
				if (FACET_FIRST.equals(facet))
					pager.firstPage();
				else if (FACET_PREVIOUS.equals(facet))
					pager.prePage();
				else if (FACET_NEXT.equals(facet))
					pager.nextPage();
				else if (FACET_LAST.equals(facet))
					pager.lastPage();
			} else {
				pager.gotoPage(pageindex);
			}
		}

	}

	protected Object getPropValue(Object setValue, String propName) {
		return getPropValue(setValue, propName, null);
	}

	protected Object getPropValue(Object setValue, String propName,
			Object defValue) {
		if (setValue != null)
			return setValue;
		else {
			ValueExpression ve = getValueExpression(propName);
			if (ve != null) {
				Object veValue = ve.getValue(getFacesContext().getELContext());
				return veValue == null ||"".equals(veValue)? defValue :veValue;
			} else
				return defValue;
		}
	}
	public Object saveState(FacesContext context) {
		if (values == null)
			values = new Object[4];
		values[0] = super.saveState(context);
		values[1] = immediate;
		values[2] = _for;
		values[3] = pagerVar;
		return values;
	}

	public void restoreState(FacesContext context, Object state) {
		values = (Object[]) (Object[]) state;
		super.restoreState(context, values[0]);
		immediate = (Boolean) values[1];
		_for = values[2];
		pagerVar = (String) values[3];

	}
}
